package com.example.caorl.jdbcaop.factory;

import com.example.caorl.jdbcaop.service.IStudentService;
import com.example.caorl.jdbcaop.util.TransactionManager;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class BeanFactory {
    private IStudentService studentService;
    private TransactionManager transactionManager;

    public final void setStudentService(IStudentService studentService) {
        this.studentService = studentService;
    }

    public void setTransactionManager(TransactionManager transactionManager) {
        this.transactionManager = transactionManager;
    }

    //使用JDK代理获取AccountService代理对象
    public IStudentService getStudentService(){
        IStudentService proxy  = (IStudentService) Proxy.newProxyInstance(
                studentService.getClass().getClassLoader(),
                studentService.getClass().getInterfaces(),


                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        try {
                            //1.开启事务
                            transactionManager.beginTransaction();
                            //2.执行操作
                            Object result = method.invoke(studentService, args);
                            //3.提交事务
                            transactionManager.commit();
                            //4.返回结果
                            return result;
                        } catch (Exception e) {
                            //5.回滚事务
                            transactionManager.rollback();
                            throw new RuntimeException(e);
                        } finally {
                            //6.释放资源
                            transactionManager.release();
                        }
                    }
                });
        return proxy;
    }


    //使用ByteBuddy代理获取AccountService代理对象
/*    public IStudentService getStudentService() throws Exception {
        return createByteBuddyDynamicProxy();
    }

    private IStudentService createByteBuddyDynamicProxy() throws Exception {
        IStudentService service = new ByteBuddy()
                .subclass(StudentServiceImpl.class) // 动态生成Service类的子类
                .method(ElementMatchers.any()) // 拦截所有方法
                .intercept(Advice.to(LoggerAdvisor.class)) // 使用LoggerAdvisor类作为拦截器，Advice是AOP的概念，似乎一般翻译为「通知」？
                .make() // 作出
                .load(StudentServiceImpl.class.getClassLoader()) // 硬塞给ClassLoader
                .getLoaded() // 拿到Class对象
                .getDeclaredConstructor() // Class.newInstance() 在Java 9中被废弃了，是个很有意思的故事，有兴趣可以去了解一下
                .newInstance();
        return  service;


    }*/


/*    static class LoggerAdvisor {
        @Advice.OnMethodEnter
        public static void onMethodEnter(@Advice.Origin Method method, @Advice.AllArguments Object[] arguments) {
            Object result = null;
            try {
                //1.开启事务
                transactionManager.beginTransaction();
                //2.执行操作
                result = method.invoke(arguments);
                //3.提交事务
                transactionManager.commit();
                //4.返回结果
            } catch (Exception e) {
                //5.回滚事务
                transactionManager.rollback();
                throw new RuntimeException(e);
            } finally {
                //6.释放资源
                transactionManager.release();

            }
        }

        @Advice.OnMethodExit
        public static void onMethodExit(@Advice.Origin Method method, @Advice.AllArguments Object[] arguments, @Advice.Return Object ret) {

        }
    }*/
}

